package com.gui.mianshiya.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gui.mianshiya.common.BaseResponse;
import com.gui.mianshiya.common.ResultUtils;
import com.gui.mianshiya.model.entity.User;
import com.gui.mianshiya.model.entity.UserSignIn;
import com.gui.mianshiya.model.vo.SignPointsVO;
import com.gui.mianshiya.service.UserService;
import com.gui.mianshiya.service.UserSignInService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;
import java.util.List;

/**
 * @Title: UserSignInController
 * @Author quit
 * @Package com.gui.mianshiya.controller
 * @Date 2025/5/5 13:19
 * @description: 用户签到表
 */

@RestController
@RequestMapping("/sign")
@Slf4j
public class UserSignInController   {

    @Resource
    private UserService userService;

    @Resource
    private UserSignInService userSignInService;


    // 基础签到积分
    private static final int BASE_POINTS = 5;
    // 连续签到额外奖励
    private static final int[] CONTINUOUS_REWARDS = {0, 0, 2, 0, 0, 0, 5};
    private static final int[] LEVEL_POINTS={0,10,30,50,100,10000};
    private static final String[] LEVEL_NAMES = {"新手鸭", "小学鸭","中学鸭", "大学鸭","硕士鸭"};
    /**
     * 添加用户签到记录
     * @param request
     * @return 当前是否有已经签到
     */
    @PostMapping("/in")
    public BaseResponse<Boolean> addUserSignIn(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if(!checkIsSign(loginUser.getId())){
            return ResultUtils.error(400,"今日已签到");
        }
        // 2. 计算连续签到天数
        int continuousDays = calculateContinuousDays(loginUser.getId());
        // 3. 计算本次签到积分
        int points = calculatePoints(continuousDays);
        // 4. 创建签到记录
        UserSignIn signIn = new UserSignIn();
        signIn.setUserId(loginUser.getId());
        signIn.setSignDate(new Date());
        signIn.setPoints(points);
        signIn.setContinuousDays(continuousDays);
        signIn.setLevels(calculateLevel(loginUser.getId(),points)); // 可以根据积分计算等级

        boolean saved = userSignInService.save(signIn);

        // 5. 更新用户总积分（假设User实体中有totalPoints字段）
        if (saved) {
            userService.updateUserPoints(loginUser.getId(), points);
        }

        return ResultUtils.success(saved);
    }

    /**
     * 判断当前用户是否签到
     * @param request
     * @return
     */
    @PostMapping("/check")
    public BaseResponse<Boolean> check(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (!checkIsSign(loginUser.getId())){
            return ResultUtils.success(true);
        }else {
            return ResultUtils.success(false);
        }
    }

    /**
     * 获取用户签到积分
     * @param request
     * @return
     */
    @PostMapping("/points")
    public BaseResponse<SignPointsVO> points(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        User user = userService.getById(loginUser.getId());
        SignPointsVO signPointsVO = new SignPointsVO();
        int index = checkPoints(user.getTotalPoints());
        signPointsVO.setPoints(user.getTotalPoints());
        signPointsVO.setLevels(index);
        signPointsVO.setLevelName(LEVEL_NAMES[index]);
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(User::getTotalPoints);
        List<User> users = userService.list(wrapper);
        // 查找指定用户位置
        for (int i = 0; i < users.size(); i++) {
            if (users.get(i).getId().equals(loginUser.getId())) {
                 signPointsVO.setLevelRanks((long) i + 1);
            }
        }
        for (int i = 0; i < LEVEL_POINTS.length; i++) {
            if (signPointsVO.getPoints() < LEVEL_POINTS[i]) {
                signPointsVO.setNextLevelPoints((long) LEVEL_POINTS[i]);
                break;
            }
        }
        return ResultUtils.success(signPointsVO);
    }


    // 计算连续签到天数
    private int calculateContinuousDays(Long userId) {
        // 1. 获取最新签到记录
        LambdaQueryWrapper<UserSignIn> latestQuery = new LambdaQueryWrapper<>();
        latestQuery.eq(UserSignIn::getUserId, userId)
                .orderByDesc(UserSignIn::getSignDate)
                .last("LIMIT 1");
        UserSignIn latest = userSignInService.getOne(latestQuery);
        if (latest == null) return 0; // 从未签到

        // 2. 检查是否是昨天签到的（连续签到）
        LocalDate lastSignDate = latest.getSignDate().toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        LocalDate yesterday = LocalDate.now().minusDays(1);

        return lastSignDate.equals(yesterday) ?
                latest.getContinuousDays() + 1 : // 连续签到
                1;                               // 重新开始
    }
    // 计算本次签到积分
    private int calculatePoints(int continuousDays) {
        int points = BASE_POINTS;
        // 连续签到奖励
        if (continuousDays > 1 && continuousDays <= CONTINUOUS_REWARDS.length) {
            points += CONTINUOUS_REWARDS[continuousDays - 1];
        } else if (continuousDays > CONTINUOUS_REWARDS.length) {
            points += 5; // 超过7天后每天固定奖励
        }
        // 周末双倍
        Date today = new Date();
        if (today.getDay() == 0 || today.getDay() == 6) { // 0是周日，6是周六
            points *= 2;
        }
        return points;
    }

    // 计算签到等级（示例）
    private int calculateLevel(Long userId,int points) {
        User user = userService.getById(userId);
        Long totalPoints = user.getTotalPoints();
        totalPoints += points;
    return  checkPoints(totalPoints) + 1;
    }

    private int checkPoints(Long totalPoints){
        //    private static final int[] LEVEL_POINTS={0,10,30,50,100};
        // private static final String[] LEVEL_NAMES = {"新手鸭", "小学鸭","中学鸭", "大学鸭","硕士鸭"};
        if (totalPoints < LEVEL_POINTS[1]) return 0; //10 小学
        if (totalPoints < LEVEL_POINTS[2]) return 1; //30 中学
        if (totalPoints < LEVEL_POINTS[3]) return 2; //50 高中
        if (totalPoints < LEVEL_POINTS[4]) return 3; // 100 大学
        if (totalPoints > 100) return 4;
        return 0;
    }

    private boolean checkIsSign(Long userId) {
        // 获取当天0点和23:59:59的时间边界（带时区处理）
        ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
        Date startOfDay = Date.from(now.with(LocalTime.MIN).toInstant());
        Date endOfDay = Date.from(now.with(LocalTime.MAX).toInstant());
        // 1. 检查今天是否已签到
        LambdaQueryWrapper<UserSignIn> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserSignIn::getUserId, userId)
                .between(UserSignIn::getSignDate, startOfDay, endOfDay);
        if (userSignInService.count(queryWrapper) > 0) {
            return false; // 今日已签到
        }
        return true;
    }
}
